package com.googlecode.icefusion.ui.commons.navigation;


import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;

import org.springframework.beans.factory.annotation.Autowired;

import com.googlecode.icefusion.ui.commons.BackingBean;
import com.googlecode.icefusion.ui.commons.constant.ICEfusionConsts;
import com.icesoft.faces.component.menubar.MenuItem;


/**
 * Dynamic menu management. Navigation ids of the static menu are used.
 * 
 * @see com.googlecode.icefusion.ui.commons.constant.Context#getDynamicMenu() dynamicMenuMode
 * 
 * @author Rainer Eschen
 * 
 */
public class DynamicMenu extends BackingBean {

	private static final long serialVersionUID = -7000315155508809970L;

	@Autowired
	private ICEfusionConsts consts;

	@Autowired
	private Menu menu;

	/**
	 * Menu structure. The class has to handle this as a singleton. If the locale is changed during a session this list
	 * has to be reseted, to load corresponding resource bundle entries again.
	 */
	ArrayList<MenuItem> dynamicMenu = new ArrayList<MenuItem>();

	/**
	 * Defines values for main menu creation: navigationId, label.
	 */
	LinkedHashMap<String, String> mainMenu = new LinkedHashMap<String, String>();

	/**
	 * Defines values for navigation menu creation: navigationId, label.
	 */
	LinkedHashMap<String, String> navigationMenu = new LinkedHashMap<String, String>();

	/**
	 * Defines values for feedback menu creation: navigationId, label.
	 */
	LinkedHashMap<String, String> feedbackMenu = new LinkedHashMap<String, String>();

	/**
	 * Defines values for presentation menu creation: navigationId, label.
	 */
	LinkedHashMap<String, String> presentationMenu = new LinkedHashMap<String, String>();

	/**
	 * Defines values for creation menu creation: navigationId, label.
	 */
	LinkedHashMap<String, String> creationMenu = new LinkedHashMap<String, String>();

	/**
	 * Defines values for push menu creation: navigationId, label.
	 */
	LinkedHashMap<String, String> pushMenu = new LinkedHashMap<String, String>();

	// ICEfusion standard entries

	/**
	 * Defines values for extra menu creation: navigationId, label.
	 */
	LinkedHashMap<String, String> extraMenu = new LinkedHashMap<String, String>();

	/**
	 * Prepare structure for menu creation.
	 */
	protected void init() {
		mainMenu.put("navigation", consts.getLocalized("application.menu.navigation", "icecube"));
		mainMenu.put("feedback", consts.getLocalized("application.menu.feedback", "icecube"));
		mainMenu.put("presentation", consts.getLocalized("application.menu.presentation", "icecube"));
		mainMenu.put("creation", consts.getLocalized("application.menu.creation", "icecube"));
		mainMenu.put("push", consts.getLocalized("application.menu.push", "icecube"));

		navigationMenu.put("pulldownMenu", consts.getLocalized("application.menu.navigation.pulldownMenu", "icecube"));
		navigationMenu.put("popupMenu", consts.getLocalized("application.menu.navigation.popupMenu", "icecube"));
		navigationMenu.put("tabbedPanel", consts.getLocalized("application.menu.navigation.tabbedPanel", "icecube"));
		navigationMenu.put("collapsiblePanel", consts.getLocalized("application.menu.navigation.collapsiblePanel",
			"icecube"));

		feedbackMenu.put("popupDialog", consts.getLocalized("application.menu.feedback.popupDialog", "icecube"));
		feedbackMenu.put("connectionStatus", consts.getLocalized("application.menu.feedback.connectionStatus",
			"icecube"));
		feedbackMenu.put("tooltip", consts.getLocalized("application.menu.feedback.tooltip", "icecube"));
		feedbackMenu.put("autocomplete", consts.getLocalized("application.menu.feedback.autocomplete", "icecube"));
		feedbackMenu.put("dragAndDrop", consts.getLocalized("application.menu.feedback.dragAndDrop", "icecube"));

		presentationMenu.put("dataTable", consts.getLocalized("application.menu.presentation.dataTable", "icecube"));
		presentationMenu.put("dataTableDynamic", consts.getLocalized("application.menu.presentation.dataTable.dynamic", "icecube"));
		presentationMenu.put("tree", consts.getLocalized("application.menu.presentation.tree", "icecube"));
		presentationMenu.put("chart", consts.getLocalized("application.menu.presentation.chart", "icecube"));
		presentationMenu.put("googleMap", consts.getLocalized("application.menu.presentation.googleMap", "icecube"));
		presentationMenu.put("mediaPlayer", consts.getLocalized("application.menu.presentation.mediaPlayer", "icecube"));

		creationMenu.put("form", consts.getLocalized("application.menu.creation.form", "icecube"));
		creationMenu.put("textEntry", consts.getLocalized("application.menu.creation.textEntry", "icecube"));
		creationMenu.put("selection", consts.getLocalized("application.menu.creation.selection", "icecube"));
		creationMenu.put("validationForm", consts.getLocalized("application.menu.creation.validationForm", "icecube"));
		creationMenu.put("calendar", consts.getLocalized("application.menu.creation.calendar", "icecube"));
		creationMenu.put("richTextEditor", consts.getLocalized("application.menu.creation.richTextEditor", "icecube"));

		pushMenu.put("popupProgressDialog", consts.getLocalized("application.menu.push.popupProgressDialog", "icecube"));
		pushMenu.put("game", consts.getLocalized("application.menu.push.game", "icecube"));

		// ICEfusion standard entries
		mainMenu.put("extra", consts.getLocalized("application.menu.extra", "icefusion"));

		extraMenu.put("settings", consts.getLocalized("application.menu.extra.settings", "icefusion"));
		extraMenu.put("about", consts.getLocalized("application.menu.extra.about", "icefusion"));
	}

	/**
	 * Adds a single entry to the main menu.
	 * 
	 * @param parent node to add the entry
	 * @param entry parameter to create a menu entry
	 */
	protected MenuItem addEntry(List<MenuItem> parent, Entry<String, String> entry) {

		MenuItem menuItem = new MenuItem();
		menuItem.setValue(entry.getValue());
		menuItem.setId(entry.getKey());
		menuItem.addActionListener(new DynamicMenuActionListener());
		parent.add(menuItem);
		return menuItem;
	}

	/**
	 * Adds a single entry to any sub menu.
	 * 
	 * @param parent node to add the entry
	 * @param entry parameter to create a menu entry
	 */
	protected MenuItem addEntry(MenuItem parent, Entry<String, String> entry) {

		MenuItem menuItem = new MenuItem();
		menuItem.setValue(entry.getValue());
		menuItem.setId(entry.getKey());
		menuItem.addActionListener(new DynamicMenuActionListener());
		parent.getChildren().add(menuItem);
		return menuItem;
	}

	/**
	 * Delivers the ICEfaces menu model to render.
	 * 
	 * @return tree of menu entries
	 */
	public List<MenuItem> getMenuModel() {

		if (!this.dynamicMenu.isEmpty()) {
			return this.dynamicMenu;
		}

		this.init();
		for (Entry<String, String> main : mainMenu.entrySet()) {
			MenuItem mainItem = this.addEntry(this.dynamicMenu, main);
			if (main.getKey().equals("navigation")) {
				for (Entry<String, String> navigation : navigationMenu.entrySet()) {
					MenuItem navigationItem = this.addEntry(mainItem, navigation);
				}
			}
			if (main.getKey().equals("feedback")) {
				for (Entry<String, String> feedback : feedbackMenu.entrySet()) {
					MenuItem feedbackItem = this.addEntry(mainItem, feedback);
				}
			}
			if (main.getKey().equals("presentation")) {
				for (Entry<String, String> presentation : presentationMenu.entrySet()) {
					MenuItem presentationItem = this.addEntry(mainItem, presentation);
				}
			}
			if (main.getKey().equals("creation")) {
				for (Entry<String, String> creation : creationMenu.entrySet()) {
					MenuItem creationItem = this.addEntry(mainItem, creation);
				}
			}
			if (main.getKey().equals("push")) {
				for (Entry<String, String> push : pushMenu.entrySet()) {
					MenuItem pushItem = this.addEntry(mainItem, push);
				}
			}

			// ICEfusion standard entries
			if (main.getKey().equals("extra")) {
				for (Entry<String, String> extra : extraMenu.entrySet()) {
					MenuItem extraItem = this.addEntry(mainItem, extra);
				}
			}
		}
		return this.dynamicMenu;
	}


	/**
	 * Resets current menu definition for locale changes.
	 */
	public void resetDynamicMenu() {
		if (this.dynamicMenu != null) {
			this.dynamicMenu.clear();
		}
	}
}
